﻿#region Copyright

// All Material Copyright © 2010 Dynamic Concepts Development Corp., All Rights Reserved.
//      Portions Copyright © 1984-2009 Dynamic Concepts Development Corp., All Rights Reserved.
// For further information please contact: SoftwareSupport@dynconcepts.com
// Dynamic Concepts Development Corp.  311 W 57th St. Suite #422, New York, NY 10019

#endregion

#region Using References

using System;
using System.Windows.Threading;
using DynConDevCorp.OpenArch.SupportLibrary.ApplicationInfrastructure;

#endregion

namespace DynConDevCorp.OpenArch.SupportLibrary.ParallelExecution
{
    internal abstract class VirtualSyncExecutionContextBase : ParallelExecutionBase
    {
        #region Constructors

        protected VirtualSyncExecutionContextBase(Object owner, Dispatcher owningDispatcher, Dispatcher executingDispatcher) : base(owner, owningDispatcher)
        {
            if (ReferenceEquals(owningDispatcher, executingDispatcher))
                throw new InvalidOperationException();
            r_ExecutingDispatcher = executingDispatcher;
        }

        #endregion

        #region Protected Methods

        protected void DispatcherOperation_Completed(object sender, EventArgs e)
        {
        }

        protected DispatcherOperation ExecuteDispatcherFrame()
        {
            base.ExecutionStarted();
            if (m_EnableLogging) QueuedLogger.GlobalInstance.Log(QueuedLogger.MessageSeverity.Debug, "Run() - Started");
            if (!ReferenceEquals(r_OwningDispatcher, Dispatcher.CurrentDispatcher))
                throw new InvalidOperationException();
            if (!r_DispatcherFrame.Continue)
                throw new Exception();
            DispatcherOperation dispatcherOperation = InvokeOperation();
            dispatcherOperation.Completed += DispatcherOperation_Completed;

            Dispatcher.PushFrame(r_DispatcherFrame);

            if (m_EnableLogging) QueuedLogger.GlobalInstance.Log(QueuedLogger.MessageSeverity.Debug, "Run() - Completed");
            return dispatcherOperation;
        }

        protected abstract void InvokeProvidedDelegate();

        protected void SetFrameComplete()
        {
            r_DispatcherFrame.Continue = false;
            base.ExecutionComplete();
        }

        #endregion

        #region Private Methods

        private void InternalInvoke()
        {
            InvokeProvidedDelegate();
            SetFrameComplete();
        }

        private DispatcherOperation InvokeOperation()
        {
            return r_ExecutingDispatcher.BeginInvoke(new InternalInvokeDelegate(InternalInvoke));
        }

        #endregion

        #region Static Fields and Constants

        private const bool c_EnableLogging = false;

        #endregion

        #region Instance Fields (ReadOnly)

        private readonly DispatcherFrame r_DispatcherFrame = new DispatcherFrame();

        #endregion

        #region Instance Fields (Mutable)

        private bool m_EnableLogging = c_EnableLogging;
        protected Dispatcher r_ExecutingDispatcher;

        #endregion

        #region Nested type: InternalInvokeDelegate

        private delegate void InternalInvokeDelegate();

        #endregion
    }
}